package com.jb.web.bean;

import com.jb.faces.context.FacesContext;
import com.jb.util.ClassUtil;
import com.jb.web.bean.event.SelectionListner;
import com.jb.web.bean.event.UIEvent;
import com.jb.web.bean.inspector.FilePropertyEditor;
import com.jb.web.context.WebContext;
import com.jb.web.model.GUID;
import com.jb.web.renderer.NodeRenderer;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.tree.TreeModel;

 
public class WebTree extends Region
    implements SelectionListner
{
    String modelName;
    public void setCloseIcon(String closeIcon)
    {
        this.closeIcon = closeIcon;
    }

    public String getCloseIcon()
    {
        return closeIcon;
    }

    public BaseComponent getComponentById(String pId)
    {
        if(mRoot != null)
        {
            if(mRoot.getQName().equals(pId))
                return mRoot;
            else
                return mRoot.getComponentById(pId);
        } else
        {
            return null;
        }
    }

    public void setLeafIcon(String leafIcon)
    {
        this.leafIcon = leafIcon;
    }

    public String getLeafIcon()
    {
        return leafIcon;
    }

    public void setModel(WebContext ctx, TreeModel model)
    {
        clearChildren();
        mModel = model;
        mRoot = getTree(ctx, model);
    }

    public void setOnSelectNode(String onSelectNode)
    {
        if(onSelectNode != null && onSelectNode.length() == 0)
            onSelectNode = null;
        this.onSelectNode = onSelectNode;
    }

    public String getOnSelectNode()
    {
        return onSelectNode;
    }

    public void setOpenIcon(String openIcon)
    {
        this.openIcon = openIcon;
    }

    public String getOpenIcon()
    {
        return openIcon;
    }

    public JBTreeNode getRootNode()
    {
        return mRoot;
    }

    public List getSelection()
    {
        ArrayList list = new ArrayList();
        if(mRoot == null)
            return list;
        if(mRoot.isSelected())
            list.add(mRoot);
        List children = mRoot.getDescendants(JBTreeNode.class);
        for(Iterator i = children.iterator(); i.hasNext();)
        {
            JBTreeNode tn = (JBTreeNode)i.next();
            if(tn.isSelected())
                list.add(tn);
        }

        return list;
    }

    public void setTreeNodeRender(String treeNodeRender)
    {
        this.treeNodeRender = treeNodeRender;
    }

    public String getTreeNodeRender()
    {
        return treeNodeRender;
    }

    public void collaps()
    {
        toggleState(mRoot, 1);
    }

    public void onSelect(WebContext ctx, UIEvent event)
    {
        buildTree(mRoot.getSelectedNode(), mModel);
    }

    public void openAll()
    {
        toggleState(mRoot, 0);
    }

    private JBTreeNode getTree(WebContext ctx, TreeModel model)
    {
        try
        {
            JBTreeNode cNode = new JBTreeNode();
            
            Object item = model.getRoot();
            if(treeNodeRender!=null && treeNodeRender.length()>0)
            try
            {
                nodeRenderer = (NodeRenderer)ClassUtil.createInstance(treeNodeRender);
                cNode.setNodeRenderer(nodeRenderer);
            }
            catch(ClassCastException e)
            {
                ctx.addErrorMessage(this, "Node Renderer does not implement "+treeNodeRender);
            }
            cNode.setNodeState(0);
            cNode.setDestination("${context.pageName}.xsp");
            cNode.setUserObject(item);
            cNode.setFontStyle(getFontStyle());
            cNode.setDesignable(false);
            cNode.addSelectListner(this);
            cNode.setSelected(true);
            cNode.setOnSelect(getOnSelectNode());
            buildTree(cNode, model);
            addChild(cNode);
            cNode.setTreeModel(model);
            JBTreeNode jbtreenode = cNode;
            return jbtreenode;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        JBTreeNode jbtreenode1 = null;
        return jbtreenode1;
    }

    private void buildTree(JBTreeNode pNode, TreeModel model)
    {
        if(pNode.getChildCount() > 0)
            return;
        pNode.clearChildren();
        Object node = pNode.getUserObject();
        int count = model.getChildCount(node);
        for(int i = 0; i < count; i++)
        {
            Object item = model.getChild(pNode.getUserObject(), i);
            JBTreeNode cNode = new JBTreeNode();
            cNode.setTreeModel(model);
            cNode.setNodeRenderer(nodeRenderer);
            cNode.setId(GUID.next(JBTreeNode.class));
            cNode.setNodeState(1);
            cNode.setUserObject(item);
            cNode.setDestination("${context.pageName}.xsp");
            cNode.setFontStyle(getFontStyle());
            pNode.addChild(cNode);
            pNode.setOpenIcon(openIcon);
            pNode.setCloseIcon(closeIcon);
            cNode.setIconImage(leafIcon);
            cNode.setDesignable(false);
        }

    }

    public void onRestored(FacesContext ctx)
    {
        super.onRestored(ctx);
        if(getRootNode() == null && getModelName() != null)
            try
            {
                TreeModel md = (TreeModel)ClassUtil.createInstance(getModelName());
                setModel((WebContext)ctx, md);
            }catch(Exception e)
            {
                //e.printStackTrace();
            }
    }

    private void toggleState(JBTreeNode pNode, int state)
    {
        if(pNode == null)
            return;
        int count = pNode.getChildCount();
        for(int i = 0; i < count; i++)
        {
            JBTreeNode mNode = pNode.getChild(i);
            mNode.setNodeState(state);
            toggleState(mNode, state);
        }

    }

    public WebTree()
    {
    }

    static final long serialVersionUID = 0x1e0f3L;
    String closeIcon;
    String leafIcon;
    String openIcon;
    String treeNodeRender;
    private JBTreeNode mRoot;
    private String onSelectNode;
    private TreeModel mModel;
    NodeRenderer nodeRenderer;

    static 
    {
        publish(WebTree.class, "General", "leafIcon", new FilePropertyEditor());
        publish(WebTree.class, "General", "openIcon", new FilePropertyEditor());
        publish(WebTree.class, "General", "closeIcon", new FilePropertyEditor());
        publish(WebTree.class, "General", "treeNodeRender");
        publish(WebTree.class, "General", "modelName");
        publish(WebTree.class, "Event Handler", "onSelectNode");
    }

    public void setModelName(String param) {
        this.modelName = param;
    }

    public String getModelName() {
        return modelName;
    }
}
